package com.coc.aspect;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import jdk.nashorn.internal.ir.JoinPredecessor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class SpecialAspect implements Ordered {

    private final static Logger logger = LoggerFactory.getLogger(SpecialAspect.class);

    @Pointcut ("execution(public * com.coc.web.AopTestController.*(..))")
    public void log(){
    }

    @Before("log()")
    public void doBefore(JoinPoint joinPoint){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Map params = new HashMap();
        params.put("url", request.getRequestURL()); // 获取请求的url
        params.put("method", request.getMethod()); // 获取请求的方式
        params.put("ip", request.getRemoteAddr()); // 获取请求的ip地址
        params.put("className", joinPoint.getSignature().getDeclaringTypeName()); // 获取类名
        params.put("classMethod", joinPoint.getSignature().getName()); // 获取类方法
        params.put("args", joinPoint.getArgs()); // 请求参数
        // 输出格式化后的json字符串
        Gson gson = new GsonBuilder().setPrettyPrinting().create();

        logger.info("Before - REQUEST: {}", gson.toJson(params));

    }

    @After("log()")
    public void doAfter(JoinPoint joinPoint){
        logger.info("After log() - {}" ,joinPoint.toString());
    }

//    @Around("log()")
    public Object doAround (ProceedingJoinPoint point) {
        try {
            Object o =  point.proceed();
            System.out.println("方法环绕proceed，结果是 :" + o);
            logger.info("Around - {}",o);
            return o;
        } catch (Throwable e) {
            // e.printStackTrace();
            logger.info("Around - {} ", e.getMessage());
            return null;
        }
    }

    @AfterReturning(returning = "object", pointcut = "log()")
    public void doAfterReturning (Object object) {
        if (object != null)
            logger.info ("AfterReturning - RESPONSE : {} ", object.toString());

    }

    @AfterThrowing(throwing = "e",pointcut = "log()")
    public void doAfterThrowing (JoinPoint joinPoint, Exception  e){
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        //开始打log
        System.out.println("异常:" + e.getMessage());
        System.out.println("异常所在类：" + className);
        System.out.println("异常所在方法：" + methodName);
        System.out.println("异常中的参数：");
        System.out.println(methodName);
        for (int i = 0; i < args.length; i++) {
            System.out.println(args[i].toString());
        }

        logger.error("AfterThrowing - {} - Exception : {} ", joinPoint ,e.getMessage());
    }


    @Override
    public int getOrder() {
        return 1;
    }
}
